package com.fang.study;

import com.fang.study.config.BeanConfig;
import com.fang.study.config.FangFactoryBean;
import com.fang.study.pojo.Person;
import com.fang.study.pojo.User;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.function.Supplier;

/**
 * @author fanglingxiao
 * @version 1.0
 * @description TODO
 * @date 2021/12/20 8:30 下午
 **/
public class Test01_CreateBean {
    public static void main(String[] args) {
        // 一、Spring bean
        // -------- 申明式 ---------
        // 1.1 <bean/>
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user = applicationContext.getBean("user", User.class);
        user.setName("Spring Bean -> xml");
        System.out.println(user.toString());
        // 1.2 @Bean
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
        User getUser = annotationConfigApplicationContext.getBean("getUser", User.class);
        getUser.setName("Spring Bean -> @Bean");
        System.out.println(getUser.toString());
        // 1.3 @component 定义@ComponentScan路径
        // -------- 编程式 ---------
        // 1.4 BeanDefinition
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition.setBeanClass(User.class);

        AnnotationConfigApplicationContext beanDefinitionContext = new AnnotationConfigApplicationContext(BeanConfig.class);
        beanDefinitionContext.registerBeanDefinition("user", beanDefinition);

        User beanDefinitionUser = beanDefinitionContext.getBean("user", User.class);
        beanDefinitionUser.setName("Spring Bean -> beanDefinition");
        System.out.println(beanDefinitionUser.toString());

        // 1.4 FactoryBean
        AbstractBeanDefinition factoryBean = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        factoryBean.setBeanClass(FangFactoryBean.class);

        AnnotationConfigApplicationContext factoryBeanContext = new AnnotationConfigApplicationContext(BeanConfig.class);
        //自定义beanName=person
        factoryBeanContext.registerBeanDefinition("person", factoryBean);
        Person factoryBeanPerson = factoryBeanContext.getBean("person", Person.class);
        factoryBeanPerson.setName("Spring Bean -> factoryBean");
        System.out.println(factoryBeanPerson.toString());
        //若想要获取FangFactoryBean对象则 &beanName => &person
        FangFactoryBean fangFactoryBean = factoryBeanContext.getBean("&person", FangFactoryBean.class);
        System.out.println("factoryBean -> address:" + fangFactoryBean);

        // 1.5 Supplier
        AnnotationConfigApplicationContext supplierContext = new AnnotationConfigApplicationContext();
        supplierContext.refresh();
        supplierContext.registerBean(Person.class, new Supplier<Person>() {
            @Override
            public Person get() {
                Person person = new Person();
                person.setName("Spring Bean -> supplier");
                return person;
            }
        });
        Person person = supplierContext.getBean("person", Person.class);
        System.out.println(person.toString());

        // 二、Java bean
        User user1 = new User();
        user1.setName("Java Bean");
        System.out.println(user1.toString());
    }
}
